package org.dromara.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.dromara.business.domain.Goods;
import org.dromara.business.domain.Post;
import org.dromara.business.domain.vo.GoodsVo;
import org.dromara.business.domain.vo.PostVo;
import org.dromara.business.domain.vo.UserVo;
import org.dromara.business.service.BusinessConfigService;
import org.dromara.business.service.GoodsService;
import org.dromara.business.service.PostService;
import org.dromara.business.service.UserService;
import org.dromara.common.core.enums.UserType;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.util.TwoQueryUtils;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysUserService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 用户信息Service业务层处理
 *
 * @author zlj
 * @date 2024-11-11
 */
@RequiredArgsConstructor
@Service
public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements UserService {

    private final SysUserMapper baseMapper;
    private final ISysUserService userService;
    private final BusinessConfigService configService;
    private final PostService postService;
    private final GoodsService goodsService;

    /**
     * 查询用户信息
     */
    @Override
    public SysUserVo queryById(Long userId) {
        SysUserVo sysUserVo = baseMapper.selectVoById(userId);
        if (ObjectUtil.equal(sysUserVo.getIsWaiter(), "1")) {
            sysUserVo.setTypeListIds(StrUtil.split(sysUserVo.getTypeIds(), ","));
        }
        return sysUserVo;
    }

    /**
     * 查询用户信息列表
     */
    @Override
    public TableDataInfo<SysUserVo> queryPageList(SysUserBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SysUser> lqw = buildQueryWrapper(bo);
        Page<SysUserVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
//        if (CollectionUtil.isNotEmpty(result.getRecords())) {
//            result.getRecords().forEach(item -> {
//                item.setTeamNum(this.lambdaQuery().eq(SysUser::getSuperiorId, item.getUserId()).count());
//            });
//        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询用户信息列表
     */
    @Override
    public List<SysUserVo> queryList(SysUserBo bo) {
        LambdaQueryWrapper<SysUser> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<SysUser> buildQueryWrapper(SysUserBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getDeptId() != null, SysUser::getDeptId, bo.getDeptId());
        lqw.like(StrUtil.isNotBlank(bo.getUserName()), SysUser::getUserName, bo.getUserName());
        lqw.like(StrUtil.isNotBlank(bo.getNickName()), SysUser::getNickName, bo.getNickName());
        lqw.eq(StrUtil.isNotBlank(bo.getUserType()), SysUser::getUserType, bo.getUserType());
        lqw.eq(StrUtil.isNotBlank(bo.getEmail()), SysUser::getEmail, bo.getEmail());
        lqw.eq(StrUtil.isNotBlank(bo.getPhonenumber()), SysUser::getPhonenumber, bo.getPhonenumber());
        lqw.eq(StrUtil.isNotBlank(bo.getOpenid()), SysUser::getOpenid, bo.getOpenid());
        lqw.eq(StrUtil.isNotBlank(bo.getUnionid()), SysUser::getUnionid, bo.getUnionid());
        lqw.eq(StrUtil.isNotBlank(bo.getSex()), SysUser::getSex, bo.getSex());
        lqw.eq(StrUtil.isNotBlank(bo.getPassword()), SysUser::getPassword, bo.getPassword());
        lqw.eq(StrUtil.isNotBlank(bo.getIsWaiter()), SysUser::getIsWaiter, bo.getIsWaiter());
        lqw.eq(StrUtil.isNotBlank(bo.getGameName()), SysUser::getGameName, bo.getGameName());
        lqw.eq(StrUtil.isNotBlank(bo.getDsVip()), SysUser::getDsVip, bo.getDsVip());
        lqw.eq(StrUtil.isNotBlank(bo.getGameArea()), SysUser::getGameArea, bo.getGameArea());
        lqw.like(StrUtil.isNotBlank(bo.getTypeIds()), SysUser::getTypeIds, bo.getTypeIds());
        lqw.eq(ObjectUtil.isNotNull(bo.getGameId()), SysUser::getGameId, bo.getGameId());
        lqw.eq(ObjectUtil.isNotNull(bo.getVip()), SysUser::getVip, bo.getVip());
//        lqw.eq(StrUtil.isNotBlank(bo.getVip()), SysUser::getVip, bo.getVip());
//        lqw.eq(StrUtil.isNotBlank(bo.getVipStatus()), SysUser::getVipStatus, bo.getVipStatus());
        lqw.eq(StrUtil.isNotBlank(bo.getStatus()), SysUser::getStatus, bo.getStatus());
//        lqw.eq(StrUtil.isNotBlank(bo.getXianxia()), SysUser::getXianxia, bo.getXianxia());
        lqw.eq(SysUser::getUserType, UserType.XCX_USER.getUserType());
//        lqw.eq(bo.getSuperiorId() != null, SysUser::getSuperiorId, bo.getSuperiorId());
        lqw.eq(bo.getUserId() != null, SysUser::getUserId, bo.getUserId());
        lqw.orderByDesc(ObjectUtil.equal(bo.getIsWaiter(), "1"), SysUser::getAllOrder);
        lqw.orderByDesc(SysUser::getAllAmount);
        return lqw;
    }

    /**
     * 新增用户信息
     */
    @Override
    public Boolean insertByBo(SysUserBo bo) {
        SysUser add = MapstructUtils.convert(bo, SysUser.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setUserId(add.getUserId());
        }
        return flag;
    }

    /**
     * 修改用户信息
     */
    @Override
    public Boolean updateByBo(SysUserBo bo) {
        SysUser update = MapstructUtils.convert(bo, SysUser.class);
        validEntityBeforeSave(update);
        if (ObjectUtil.equal(bo.getIsWaiter(), "1")) {
            update.setTypeIds(CollectionUtil.join(bo.getTypeListIds(), ","));
        }
        return userService.updateById(update);
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SysUser entity) {
//        if (ObjectUtil.isNotNull(entity.getSuperiorId())) {
//            //不能绑定自己的下级
//            boolean isDown = userService.isDown(entity.getUserId(), entity.getSuperiorId());
//            if (isDown) {
//                throw new ServiceException("上级不能绑定自己和下级");
//            }
//        }
    }

    /**
     * 批量删除用户信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {

        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public UserVo getUserInfo(Long userId) {
        SysUser user = this.getById(userId);
        UserVo vo = BeanUtil.toBean(user, UserVo.class);
        List<Post> postList = postService.lambdaQuery().eq(Post::getWaiterId, userId).list();
        vo.setPostList(BeanUtil.copyToList(postList, PostVo.class));
        if (CollectionUtil.isNotEmpty(postList)) {
            //发布人信息
            TwoQueryUtils.setField(vo.getPostList(), PostVo::getCreateBy, SysUser::getUserId, userService, PostVo::setUser);
            for (PostVo record : vo.getPostList()) {
                record.setUserVo(BeanUtil.toBean(record.getUser(), SysUserVo.class));
                record.setUser(null);
                record.setCreateTimeStr(DateUtils.getTimeStr(record.getCreateTime()));
            }
        }

        String typeIds = user.getTypeIds();
        if (StrUtil.isNotBlank(typeIds)) {
            List<Goods> goodsList = goodsService.lambdaQuery().in(Goods::getOneTypeId, StrUtil.split(typeIds, ",")).list();
            vo.setGoodsList(BeanUtil.copyToList(goodsList, GoodsVo.class));
            goodsService.setPrice(vo.getGoodsList());
        }
        return vo;
    }
}
